﻿using NuMvvm.Services;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace NuMvvm
{
    public class ViewModelLocationService
    {
        static ViewModelLocationService()
        {
            ViewModelResolver = (viewType) =>
            {
                var view = viewType.FullName.Substring(viewType.FullName.LastIndexOf('.') + 1);
                var ns = viewType.FullName.Substring(0, viewType.FullName.LastIndexOf('.'));

                var baseName = view.Replace("Page", "").Replace("View", "");
                ns = ns.Replace(".Views", ".ViewModels");
                var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
                var viewModelName = String.Format(CultureInfo.InvariantCulture, "{0}.{1}ViewModel, {2}", ns, baseName, viewAssemblyName);
                return Type.GetType(viewModelName);
            };

            ViewModelFactory = (viewModelType) =>
            {
                return Activator.CreateInstance(viewModelType);
            };
        }

        public static Func<Type, Type> ViewModelResolver { get; private set; }

        public static void SetViewModelResolver(Func<Type, Type> viewModelResolver)
        {
            ViewModelResolver = viewModelResolver;
        }

        public static Func<Type, object> ViewModelFactory { get; private set; }

        public static void SetViewModelFactory(Func<Type, object> viewModelFactory)
        {
            ViewModelFactory = viewModelFactory;
        }

        public static IView AutowireViewModelForView(IView view)
        {
            var viewModel = GetViewModelForView(view);
            view.DataContext = viewModel;
            return view;
        }

        private static object GetViewModelForView(IView view)
        {
            var viewType = view.GetType();
            var viewModelType = ViewModelResolver(viewType);
            if (viewModelType == null)
                throw new InvalidOperationException("Could not resolve the view model.");
            return ViewModelFactory(viewModelType);
        }
    }
}
